const Goods = require("../model/goods.model");

class GoodsService {
  /**
   * 操作数据库是异步的，这里使用 async/await 处理异步操作：
   * - async 用于声明异步函数，其返回值会被自动包装为 Promise 对象（无论是否显式 return Promise）。
   * - await 只能在 async 函数内使用，用于等待异步操作完成。
   * - 若 async 函数内没有 await，其执行方式与普通函数一致（同步执行，返回 Promise）。
   */

  /**
   * 执行Sequelize的create方法创建一条商品数据
   * @param {*} goods 要创建的商品信息
   * @returns 创建结果
   */
  async createGoods(goods) {
    /**
     * 插入数据（数据库操作是异步的，返回 Promise）
     * await 的执行逻辑：
     * 1. 右侧表达式若为 Promise，等待其状态变为 resolved/rejected；
     *    若不是 Promise，会被包装为一个已 resolved 的 Promise（如 await 123 等价于 await Promise.resolve(123)）。
     * 2. 暂停当前 async 函数的执行，将后续代码（await 之后的代码）放入微任务队列。
     * 3. 先执行当前事件循环中剩余的同步代码，再执行微任务队列中的代码。
     * 4. 最后恢复 async 函数的执行，继续处理 await 之后的逻辑。
     */
    const res = await Goods.create(goods);
    // 返回插入后的数据（Sequelize 实例的 dataValues 属性包含原始数据）
    return res.dataValues;
  }

  /**
   * 根据id更新商品数据
   * @param {*} id 要修改的商品id
   * @param {*} goods 新的商品信息
   * @returns 修改结果
   */
  async updateGoods(id, goods) {
    // Sequelize 提供了多种方法来协助查询数据库中的数据。如 create destroy update findAll 这四个增删改查方法，也有其他方法。
    const res = await Goods.update(goods, { where: { id } });
    // 更新数据返回的res是一个数组，res[0]是受影响的行数，如果res[0]大于0则说明至少更新了一条数据
    return res[0] > 0 ? true : false;
  }
  /**
   * 根据id删除商品数据
   * @param {*} id 商品id
   * @returns 删除结果
   */
  async removeGoods(id) {
    // Sequelize 提供了多种方法来协助查询数据库中的数据。如 create destroy update findAll 这四个增删改查方法，也有其他方法。
    const res = await Goods.destroy({ where: { id } });
    // res是受影响的行数，如果res大于0则说明至少影响了一条数据
    return res > 0 ? true : false;
  }
  async restoreGoods(id) {
    // Sequelize 提供了多种方法来协助查询数据库中的数据。如 create destroy update findAll 这四个增删改查方法，也有其他方法。
    const res = await Goods.restore({ where: { id } });
    // res是受影响的行数，如果res大于0则说明至少影响了一条数据
    return res > 0 ? true : false;
  }
  async findGoods(pageNum, pageSize) {
    // pageSize * 1的目的: 把字符型隐式地转换成数字型，避免SQL语句查询出现语法错误
    pageNum = pageNum * 1;
    pageSize = pageSize * 1;
    const offset = (pageNum - 1) * pageSize;
    // 获取总数
    // const count = await Goods.count();
    /**
     * 获取分页的数据
     * offset: 偏移量
     * limit: 每页显示多少条
     */
    // const rows = await Goods.findAll({ offset: offset, limit: pageSize });

    // Sequelize 提供了 findAndCountAll 方法（findAndCountAll结合了上面的count和findAll方法）来处理分页查询
    const { count, rows } = await Goods.findAndCountAll({ offset: offset, limit: pageSize });
    const result = {
      pageNum,
      pageSize,
      total: count,
      list: rows,
    };
    return result;
  }
}

module.exports = new GoodsService();
